﻿using mozhi.smarterp.Business.Enums;
using Mozhi.Abp.Domain.AuthorCenter;
using Mozhi.Abp.Domain.BasicData;
using System;
using System.Collections.Generic;
using System.Linq;
using Volo.Abp;

namespace mozhi.smarterp.Business.Sales
{
    /// <summary>
    /// 销售报价单
    /// </summary>
    public class SaleQuotation : DocumentAggregateRoot<SaleQuotationItem>
    {
        public Guid CustomerId { get; private set; }

        public Customer Customer { get; private set; }

        public string Address { get; private set; }

        public SaleQuotationType Type { get; private set; }

        /// <summary>
        /// 销售员
        /// </summary>
        public Guid? SalesPersonId { get; private set; }

        public Employee SalePerson { get; private set; }

        /// <summary>
        /// 生效日期
        /// </summary>
        public DateTime? EffectiveDate { get; private set; }

        /// <summary>
        /// 失效日期
        /// </summary>
        public DateTime? ExpirationDate { get; private set; }

        private SaleQuotation() { }

        public SaleQuotation(Guid id, string number, DateTime date, bool includeTax, Customer customer, string address, Currency currency, decimal exchangeRate, Department department, Employee salePerson,
            DateTime? effectiveDate, DateTime? expirationDate, string comment, SaleQuotationType type)
            : base(id, number, date, includeTax, currency, exchangeRate, department, comment)
        {
            Id = id;

            Change(number, date, includeTax, customer, address, currency, exchangeRate, department, salePerson, effectiveDate, expirationDate, comment, type);

            Items = new List<SaleQuotationItem>();
        }

        public void Change(string number, DateTime date, bool includeTax, Customer customer, string address, Currency currency, decimal exchangeRate, Department department,
            Employee salePerson, DateTime? effectiveDate, DateTime? expirationDate, string comment, SaleQuotationType type)
        {
            base.Change(number, date, includeTax, currency, exchangeRate, department, comment);

            Customer = customer;
            SalePerson = salePerson;

            CustomerId = Customer == null ? default : Customer.Id;
            Address = address;
            SalesPersonId = SalePerson?.Id;

            EffectiveDate = effectiveDate;
            ExpirationDate = expirationDate;
            Type = type;

            Validate();
        }

        #region
        protected override void Validate()
        {
            base.Validate();


            if (Customer == null)
                throw new UserFriendlyException("客户不存在", "100000");

            Customer.Validate();

            if (SalePerson != null)
                SalePerson.Validate();
        }

        protected override void AddOrUpdateItem(SaleQuotationItem item)
        {
            if (Status == DocumentStatusType.Approved)
                throw new UserFriendlyException("审核单据不允许修改", "100000");

            if (!item.Product.Saleable)
                throw new UserFriendlyException($"产品：{item.Product.Code}-{item.Product.Name}不允许销售", "100000");

            if (Type == SaleQuotationType.Standard && item.Product.Type != (int)ProductType.Stock)
                throw new UserFriendlyException($"标准销售只能选择库存类产品", "100000");

            var match = Items.FirstOrDefault(x => x.Id == item.Id);

            if (match == null)
            {
                match = item;

                match.CalculateBaiscUnitQuantity();
                match.CalculateAmount(IncludeTax, ExchangeRate);
                
                Items.Add(match);
            }

            else
            {
                match.Change(item.Product, item.AuxiliaryUnit, item.ProductAuxiliaryUnit, item.AuxiliaryQuantity, item.Price, item.TaxRate,
                    item.IsGift, item.Remark);

                item.CalculateBaiscUnitQuantity();
                item.CalculateAmount(IncludeTax, ExchangeRate);
                
            }
        }

        #endregion
    }

    public class SaleQuotationItem : DocumentEntity
    {
        public bool IsGift { get; private set; }


        private SaleQuotationItem() { }


        public SaleQuotationItem(Guid id, Product product, Unit saleUnit, ProductAuxiliaryUnit productAuxiliaryUnit, decimal saleQuantity, decimal price, TaxRate taxRate, bool isGift, string remark) :
            base(id, product, saleUnit, productAuxiliaryUnit, saleQuantity, price, taxRate, remark)
        {
            SetIsGift(isGift);

            Validate();
        }

        public void Change(Product product, Unit saleUnit, ProductAuxiliaryUnit productAuxiliaryUnit, decimal saleQuantity, decimal price, TaxRate taxRate, bool isGift, string remark)
        {
            base.Change(product, saleUnit, productAuxiliaryUnit, saleQuantity, price, taxRate, remark);

            SetIsGift(isGift);

            Validate();
        }

        #region
        private void SetIsGift(bool isGift)
        {
            IsGift = isGift;

            if (isGift)
            {
                Price = 0;
                TaxRate = null;
            }
        }

        protected override void Validate()
        {
            base.Validate();

            if (AuxiliaryUnit == null)
                throw new UserFriendlyException("销售单位不存在", "100000");

            if (AuxiliaryQuantity <= 0)
                throw new UserFriendlyException("销售数量必须大于0", "100000");

            if (IsGift)
                return;

            if (Price <= 0)
                throw new UserFriendlyException("单价必须大于0");
        }
        #endregion
    }
}
